LL_RCC_DeInit API migration

The LL de-initialization functions previously available in the stm32tnxx_ll_rcc.c files within HAL1 are no longer present in HAL2. In HAL2, all LL C files ( stm32tnxx_ll_rcc.c) have been removed, leaving only the LL header files ( stm32tnxx_ll_rcc.h) that contain static inline functions.

If users need de-initialize RCC using the LL layer, they have two methods:

  • Utilize STM32CubeMX2 Code Generation: Rely on STM32CubeMX2 to generate code with the LL layer for RCC de-initialization.

  • Replace manually the initialization and de-initialization functionsReplace the LL_RCC_DeInit functions

    manually with equivalent sequences using the static inline functions provided in the stm32tnxx_ll_rcc.h file, tailored to their specific configuration and requirements.

This approach ensures that the de-initialization sequences are precisely addressing the given use case based on the LL static inline functions provided in the stm32tnxx_ll_rcc.h header file. The sequences offer improved footprint optimization compared to the previous LL initialization functions found in stm32tnxx_ll_rcc.c.

Related concept: Remove stm32tnxx_ll_ppp.c files

Utilize STM32CubeMX2 Code Generation

LL RCC configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

LL RCC clock configuration

  • The RCC system clock source.

  • The AHB and APBx prescaler.

  • The cortex clock source and divider.

  • The peripherals kernel clock sources.

All these configurations can be performed either in the graphical view (as shown in the previous picture) or using the table view. The table view can make it easier to find the relevant configuration thanks to the “Search by Feature id” capability.

Project configuration panel

LL RCC main features configuration

The RCC Main features block configure:

  • The Flash latency (wait states).

  • The Flash programming delay.

  • The HSE source, its startup timeout and the Clock Security System.

  • The LSE source, its startup timeout, drive capability and the Clock Security System.

RCC main feature configuration

LL RCC advanced features configuration

Configure the advanced RCC features.

RCC advanced feature configuration

LL RCC GPIO configuration

Configure GPIO pins only if the MCU uses an external oscillator (HSE/LSE) and/or you need to output a clock on MCO or LSCO.

RCC GPIO configuration

LL RCC EXTI configuration

Configure the EXTI line for LSECSS.

RCC EXTI configuration

LL RCC NVIC configuration

Configure the NVIC in case of an interrupt.

RCC NVIC configuration

Generated RCC initialization sequence

The RCC initialization and de-initialization sequences are generated in the mx_rcc_init and mx_rcc_deinit functions in mx_rcc.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

STM32CubeMX2 Generated : RCC initialization sequence

Topic

Code Snippet HAL1

Code Snippet HAL2

Init and config sequence function

void SystemClock_Config(void)
{
   LL_FLASH_SetLatency(LL_FLASH_LATENCY_1);
   while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_1)
   {
   }

   LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE3);
   while (LL_PWR_IsActiveFlag_VOS() == 0)
   {
   }
   LL_RCC_HSI_Enable();

      /* Wait till HSI is ready */
   while(LL_RCC_HSI_IsReady() != 1)
   {
   }

   LL_RCC_HSI_SetCalibTrimming(16);
   LL_PWR_EnableBkUpAccess();
   while (LL_PWR_IsEnabledBkUpAccess () == 0U)
   {
   }

   LL_RCC_LSI_Enable();

      /* Wait till LSI is ready */
   while(LL_RCC_LSI_IsReady() != 1)
   {
   }

   LL_RCC_MSIS_Enable();

      /* Wait till MSIS is ready */
   while(LL_RCC_MSIS_IsReady() != 1)
   {
   }

   LL_RCC_MSI_EnableRangeSelection();
   LL_RCC_MSIS_SetRange(LL_RCC_MSISRANGE_0);
   LL_RCC_MSI_SetCalibTrimming(16, LL_RCC_MSI_OSCILLATOR_0);
   LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSIS);

      /* Wait till System clock is ready */
   while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSIS)
   {
   }

   LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
   LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
   LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
   LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1);

   LL_Init1msTick(48000000);

   LL_SetSystemCoreClock(48000000);
   LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_SYSCLK, LL_RCC_MCO1_DIV_1);
   LL_RCC_LSCO_Enable();
   LL_RCC_LSCO_SetSource(LL_RCC_LSCO_CLKSOURCE_LSI);
}
system_status_t mx_rcc_init(void)
{
   LL_RCC_HSIS_Enable();
   while(LL_RCC_HSIS_IsReady() != 1U)
   {
   }

   LL_RCC_ConfigPSI(LL_RCC_PSIFREQ_144MHZ, LL_RCC_PSIREF_8MHZ, LL_RCC_PSISOURCE_HSIDIV18);

   LL_RCC_PSIS_Enable();
   while(LL_RCC_PSIS_IsReady() != 1U)
   {
   }

   /** Initializes the CPU, AHB and APB bus clocks */
   LL_RCC_ConfigBusClock(LL_RCC_HCLK_PRESCALER_1 | LL_RCC_APB1_PRESCALER_1 |
                           LL_RCC_APB2_PRESCALER_1 | LL_RCC_APB3_PRESCALER_1);

   /** Frequency will be increased */
   LL_FLASH_SetLatency(FLASH, LL_FLASH_LATENCY_4WS);
   LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PSIS);
   /* Wait till System clock is ready */
   while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PSIS)
   {
   }

   LL_FLASH_SetProgrammingDelay(FLASH, LL_FLASH_PROGRAM_DELAY_2);

   /** Systick Initialization */
   /* LL_RCC_SetSystickClockSource(LL_RCC_SYSTICK_CLKSOURCE_HCLKDIV8); */

   LL_SetSystemCoreClock(144000000U);
   LL_Init1msTick(SystemCoreClock);

   /** Configure MCO (clock source, IO and divider) */

   LL_RCC_LSI_Enable();
   while(LL_RCC_LSI_IsReady() != 1U)
   {
   }

   /* GPIO Clocks activation */
   LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH | LL_AHB2_GRP1_PERIPH_GPIOB);

   /**
      RCC GPIO Configuration

      [GPIO Pin] ------> [Signal Name]

         PH0     ------>   RCC_OSC_IN
         PH1     ------>   RCC_OSC_OUT
      **/

   /* Configure IO output speed (Low, Medium, High or Very-High) */
   LL_GPIO_SetPinSpeed(GPIOH, LL_GPIO_PIN_0, LL_GPIO_SPEED_FREQ_HIGH);
   LL_GPIO_SetPinSpeed(GPIOH, LL_GPIO_PIN_1, LL_GPIO_SPEED_FREQ_HIGH);

   /* Configure IO output type (Push-Pull or Open-Drain) */
   LL_GPIO_SetPinOutputType(GPIOH, LL_GPIO_PIN_0 | LL_GPIO_PIN_1, LL_GPIO_OUTPUT_OPENDRAIN);

   /* Activate the Pull-up, Pull-down resistor, or No pull for the current IO */
   LL_GPIO_SetPinPull(GPIOH, LL_GPIO_PIN_0, LL_GPIO_PULL_NO);
   LL_GPIO_SetPinPull(GPIOH, LL_GPIO_PIN_1, LL_GPIO_PULL_NO);

   /* Configure IO direction mode (Input, Output, Alternate or Analog) */
   LL_GPIO_SetPinMode(GPIOH, LL_GPIO_PIN_0, LL_GPIO_MODE_ALTERNATE);
   LL_GPIO_SetPinMode(GPIOH, LL_GPIO_PIN_1, LL_GPIO_MODE_ALTERNATE);

   /**
      RCC GPIO Configuration

      [GPIO Pin] ------> [Signal Name]

         PH2     ------>   RCC_MCO1
      **/

   /* Configure IO output speed (Low, Medium, High or Very-High) */
   LL_GPIO_SetPinSpeed(GPIOH, LL_GPIO_PIN_2, LL_GPIO_SPEED_FREQ_LOW);

   /* Configure IO output type (Push-Pull or Open-Drain) */
   LL_GPIO_SetPinOutputType(GPIOH, LL_GPIO_PIN_2, LL_GPIO_OUTPUT_PUSHPULL);

   /* Activate the Pull-up, Pull-down resistor, or No pull for the current IO */
   LL_GPIO_SetPinPull(GPIOH, LL_GPIO_PIN_2, LL_GPIO_PULL_NO);

   /* Configure IO direction mode (Input, Output, Alternate or Analog) */
   LL_GPIO_SetPinMode(GPIOH, LL_GPIO_PIN_2, LL_GPIO_MODE_ALTERNATE);

   /**
      RCC GPIO Configuration

      [GPIO Pin] ------> [Signal Name]

         PB2     ------>   RCC_LSCO
      **/

   /* Activate the Pull-up, Pull-down resistor, or No pull for the current IO */
   LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_2, LL_GPIO_PULL_NO);

   /* Configure IO direction mode (Input, Output, Alternate or Analog) */
   LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_2, LL_GPIO_MODE_ANALOG);

   LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_SYSCLK, LL_RCC_MCO1_PRESCALER_1);
   /* Disable RTC Domain Write Protection */
   LL_PWR_DisableRTCDomainWriteProtection();
   LL_RCC_ConfigLSCO(LL_RCC_LSCO_CLKSOURCE_LSI);
   LL_RCC_LSCO_Enable();
   /* Enable RTC Domain Write Protection */
   LL_PWR_EnableRTCDomainWriteProtection();

   return SYSTEM_OK;
}

Deinit sequence function

void MX_RCC_DeInit(void)
{
  if (LL_RCC_DeInit(void) != HAL_OK)
  {
    Error_Handler();
  }
}
void mx_rcc_deinit(void)
{
   /* LL RCC Reset not yet available */
}

Method 2: Replace manually the initialization and de-initialization functions

LL_RCC_Init() API migration

RCC Mode Comparison between HAL1 and HAL2

HAL1

HAL2

LL_RCC_InitTypeDef rcc_InitStruct;

RCC_InitStruct.HourFormat      = LL_RCC_HOURFORMAT_24HOUR;
RCC_InitStruct.AsynchPrescaler = 127;
RCC_InitStruct.DigitalFilter   = 255;

LL_RCC_Init(RCC, &rcc_InitStruct);
LL_RCC_DisableWriteProtection();

LL_RCC_EnableInitMode();
LL_RCC_TIME_SetFormat(RCC, LL_RCC_TIME_FORMAT_AM_24H);
LL_RCC_SetSynchPrescaler(RCC, 127);
LL_RCC_SetAsynchPrescaler(RCC, 255);
LL_RCC_DisableInitMode();

LL_RCC_EnableWriteProtection(void)

LL_RCC_DeInit() API migration

Comparison of HAL1 and HAL2

HAL1

HAL2

LL_RCC_DeInit(RCC)
LL_RCC_DisableWriteProtection();

LL_RCC_EnableInitMode();

LL_RCC_WRITE_REG(RCC->TR,       0U);
LL_RCC_WRITE_REG(RCC->DR, (RCC_DR_WDU_0 | RCC_DR_MU_0 | RCC_DR_DU_0));
LL_RCC_WRITE_REG(RCC->CR,       0U);
LL_RCC_WRITE_REG(RCC->WUTR,     RCC_WUTR_WUT);
LL_RCC_WRITE_REG(RCC->PRER, (RCC_PRER_PREDIV_A | RCC_SYNCH_PRESC_DEFAULT));
LL_RCC_WRITE_REG(RCC->ALRMAR,   0U);
LL_RCC_WRITE_REG(RCC->ALRMBR,   0U);
LL_RCC_WRITE_REG(RCC->SHIFTR,   0U);
LL_RCC_WRITE_REG(RCC->CALR,     0U);
LL_RCC_WRITE_REG(RCC->ALRMASSR, 0U);
LL_RCC_WRITE_REG(RCC->ALRMBSSR, 0U);

LL_RCC_DisableInitMode();